package top.misspro.valheimadminsocket.handler;

import io.netty.channel.ChannelHandlerContext;
import io.netty.channel.SimpleChannelInboundHandler;
import io.netty.handler.codec.http.websocketx.WebSocketFrame;
import lombok.extern.slf4j.Slf4j;
import top.misspro.valheimadminsocket.server.Client;
import top.misspro.valheimadminsocket.server.ServerContains;
import top.misspro.valheimadminsocket.util.ChannelUtils;

import java.util.Date;

/**
 * @author Evan
 */
@Slf4j
abstract class AbstractHandler<T extends WebSocketFrame> extends SimpleChannelInboundHandler<Object> {

    @Override
    public void channelRegistered(ChannelHandlerContext ctx) throws Exception {
        log.debug("客户端连接！ID：" + ctx.channel().id().asLongText());
        //保存客户端状态
        Client client = Client.builder()
                .channel(ctx.channel())
                .connDate(new Date())
                .status(ServerContains.ServerStatus.UN_CONNECT).build();
        ServerContains.CLIENT_MAP.put(ChannelUtils.getChannelId(ctx.channel()), client);
    }

    @Override
    public void channelActive(ChannelHandlerContext ctx) throws Exception {
        log.debug("客户端活跃！ID：" + ctx.channel().id().asLongText());
    }

    @Override
    protected void channelRead0(ChannelHandlerContext ctx, Object msg) throws Exception {
        try {
            messageHandler(ctx, (T) msg);
        }catch (ClassCastException e){
            log.error("未实现信息类型："+msg.getClass().getName()+"的处理类！");
        }

    }
    /**
     * 客户端断开连接
     *
     * @param ctx
     * @throws Exception
     */
    @Override
    public void channelInactive(ChannelHandlerContext ctx) throws Exception {
        log.info("客户端:" + ctx.channel().id().asLongText() + "断开连接");
        //移除客户端
        ServerContains.CLIENT_MAP.remove(ChannelUtils.getChannelId(ctx.channel()));
    }

    /**
     * 发生异常
     *
     * @param channelHandlerContext
     * @param cause
     * @throws Exception
     */
    @Override
    public void exceptionCaught(ChannelHandlerContext channelHandlerContext, Throwable cause) throws Exception {
        log.error("通道消息处理发生异常!");
        cause.printStackTrace();
//        channelHandlerContext.close();
    }

    /**
     * 文本信息处理方法
     *
     * @param ctx
     * @param msg
     */
    protected abstract void messageHandler(ChannelHandlerContext ctx, T msg);
}
